/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spring;

import java.awt.*;

/**
 *
 * @author spring
 */
public class PlotPanel1 extends javax.swing.JPanel {

    double[][] locMatrix = null;
    FeedAnalyzer FA;

    public PlotPanel1() {
    }

    public void setAccess(FeedAnalyzer fa) {
        FA = fa;
    }

    public void setMatrix(double[][] M) {
        locMatrix = new double[M.length][2];
        
         for (int i = 0; i < locMatrix.length; i++) {
           locMatrix[i][0] = M[i][0];
           locMatrix[i][1] = M[i][1];   
           //System.out.println("InitCoords: "+locMatrix[i][0]+","+locMatrix[i][1]);
         }
    }
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if (locMatrix == null) {
            return;
        }
        int h = this.getHeight();
        int w = this.getWidth();
        int s = locMatrix.length;
        char[] NODES = new char[52];
        for (int i = 0; i < 26; i++) {
            NODES[i] = (char) (i + 65);
            NODES[i + 26] = (char) (i + 97);
        }
        int it;
        double[][] loc = new double[s][2];
        double[][] plotMatrix = new double[s][s];
        double[][] grad = new double[s][2];
        double lasterror = 0.0, totalerror = 0.0, errorcomp = 0.0;
        double rate = FA.rate;
        boolean first = true;
        
        g.setColor(new java.awt.Color(0, 0, 255));
        g.setFont(new java.awt.Font("Arial", java.awt.Font.BOLD, 20));
        
        for (int i = 0; i < s; i++) {
            loc[i][0] = locMatrix[i][0];
            loc[i][1] = locMatrix[i][1];
            g.drawChars(NODES, i % 52, 1, (int) (loc[i][0] * w), (int) (loc[i][1] * h));
            for (int j=0;j<s;j++)
                plotMatrix[i][j]=0.0;
        }
        //iterate upto 1000 times to place the entries
        for (it = 0; it < 1000; it++) {
            // find plot distances
            for (int i = 0; i < s; i++) {
                for (int j = 0; j < s; j++) {
                    plotMatrix[i][j] = getDistance(loc[i], loc[j]);
                }
            }//end find plot distances
            for (int i = 0; i < s; i++) {
                grad[i][0] = 0.0;
                grad[i][1] = 0.0;
            }
            // find error in plots
            totalerror = 0.0;
            for (int j = 0; j < s; j++) {
                for (int k = 0; k < s; k++) {
                    if (j == k){
                        continue;}
                    if (plotMatrix[k][j] < 0.000001) {
                        continue;
                    }
                    if (FA.distMatrix[k][j] < 0.000001) {
                        errorcomp= plotMatrix[k][j];
                    }
                    else{
                        errorcomp = (plotMatrix[k][j] - FA.distMatrix[k][j]) / FA.distMatrix[k][j];
                        // System.out.println("EC="+errorcomp);
                    }
                    grad[j][0] += ((loc[j][0] - loc[k][0]) / plotMatrix[k][j]) * errorcomp;
                    grad[j][1] += ((loc[j][1] - loc[k][1]) / plotMatrix[k][j]) * errorcomp;
                    totalerror += Math.abs(errorcomp);
                }
            }
            if (!first && lasterror < totalerror) {
                break;
            }
            first = false;
            lasterror = totalerror;
            //System.out.println("Total Iterations "+it+": Total error = "+totalerror);
            g.setColor(new java.awt.Color((it / 4), 0, 255 - (it / 4)));
            for (int j = 0; j < s; j++) {
                loc[j][0] -= rate * grad[j][0];
                loc[j][1] -= rate * grad[j][1];
             /*   if (loc[j][0] < .2) {
                    loc[j][0] = .2;
                }
                if (loc[j][0] > .8) {
                    loc[j][0] = .8;
                }
                if (loc[j][1] < .1) {
                    loc[j][1] = .1;
                }
                if (loc[j][1] > .9) {
                    loc[j][1] = .9;
                } */
                g.drawChars(NODES, j % 52, 1, (int) (loc[j][0] * w), (int) (loc[j][1] * h));
            }
        }// end iteration for 1000
        for (int j = 0; j < s; j++) {
            g.setColor(new java.awt.Color(255, 255, 255));
            g.setFont(new java.awt.Font("Arial", java.awt.Font.BOLD, 25));
            g.drawChars(NODES, j % 52, 1, (int) (loc[j][0] * w), (int) (loc[j][1] * h));
            g.setColor(new java.awt.Color(0, 0, 0));
            g.setFont(new java.awt.Font("Arial", java.awt.Font.BOLD, 13));
            FontMetrics fm = g.getFontMetrics();
            if (FA.feeds){
                g.drawString(FA.SFeed[j].getTitle(),
                        (int)(loc[j][0]*w)-fm.stringWidth(FA.SFeed[j].getTitle())/2, 
                        (int)(loc[j][1]*h)+25);
            }  
            if (FA.entries){
                g.drawString(FA.EntryTitles[j], 
                        (int)(loc[j][0]*w)-fm.stringWidth(FA.EntryTitles[j])/2, 
                        (int)(loc[j][1]*h)+25);
            }
        }
    }

    private double getDistance(double[] scores1, double[] scores2) {
        double sum = 0.0;
        for (int i = 0; i < scores1.length; i++) {
            sum += Math.pow((scores2[i] - scores1[i]), 2.0);

        }
        double distance = Math.sqrt(sum);
        return distance;
    }
}
